From: Jan Beulich Date: Mon, 27 Oct 2014 15:43:12 +0000 (+0100) Subject: x86: tolerate running on EFI runtime services page tables in map_domain_page() X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~4124 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=e65436ba36be8f1b735573d8fc9af7d8a053ba5f;p=xen.git x86: tolerate running on EFI runtime services page tables in map_domain_page() In the event of a #PF while in an EFI runtime service function we otherwise can't dump the page tables, making the analysis of the problem more cumbersome. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper --- diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c index 3903952d2d..158a1645d7 100644 --- a/xen/arch/x86/domain_page.c +++ b/xen/arch/x86/domain_page.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -37,11 +38,14 @@ static inline struct vcpu *mapcache_current_vcpu(void) */ if ( unlikely(pagetable_is_null(v->arch.guest_table)) && is_pv_vcpu(v) ) { + unsigned long cr3; + /* If we really are idling, perform lazy context switch now. */ if ( (v = idle_vcpu[smp_processor_id()]) == current ) sync_local_execstate(); /* We must now be running on the idle page table. */ - ASSERT(read_cr3() == __pa(idle_pg_table)); + ASSERT((cr3 = read_cr3()) == __pa(idle_pg_table) || + (efi_enabled && cr3 == efi_rs_page_table())); } return v; diff --git a/xen/arch/x86/efi/stub.c b/xen/arch/x86/efi/stub.c index 8916a2ec7b..b8f49f873d 100644 --- a/xen/arch/x86/efi/stub.c +++ b/xen/arch/x86/efi/stub.c @@ -9,6 +9,12 @@ const bool_t efi_enabled = 0; void __init efi_init_memory(void) { } +paddr_t efi_rs_page_table(void) +{ + BUG(); + return 0; +} + unsigned long efi_get_time(void) { BUG(); diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c index 1c43d109fc..553ff91702 100644 --- a/xen/common/efi/runtime.c +++ b/xen/common/efi/runtime.c @@ -98,6 +98,11 @@ void efi_rs_leave(unsigned long cr3) stts(); } +paddr_t efi_rs_page_table(void) +{ + return virt_to_maddr(efi_l4_pgtable); +} + unsigned long efi_get_time(void) { EFI_TIME time; diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h index 8a2b78892d..5e02724572 100644 --- a/xen/include/xen/efi.h +++ b/xen/include/xen/efi.h @@ -28,6 +28,7 @@ struct xenpf_efi_runtime_call; struct compat_pf_efi_runtime_call; void efi_init_memory(void); +paddr_t efi_rs_page_table(void); unsigned long efi_get_time(void); void efi_halt_system(void); void efi_reset_system(bool_t warm);